﻿//-----------------------------------------------------------------------
// <copyright file="MessageBoxContent.cs" company="Noboru Project">
//      Copyright (c) Noboru Project. All rights reserved.
//
//      This source code is subject to terms and conditions of the New BSD License (BSD).
//      A copy of the license can be found in the License.html file at the root of this 
//      distribution. If you can not locate the New BSD License (BSD), please send an 
//      email to noboru_adm@live.com.
//      By using this source code in any fashion, you are agreeing to be bound by
//      the terms of the New BSD License (BSD) for Noboru.
//
//      You must not remove this notice, or any other, from this software.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Noboru.Windows.Controls
{
    /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.Class"]/*' />
    [TemplatePart(Name = "LayoutPart", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "MessagePart", Type = typeof(TextBlock))]
    [TemplatePart(Name = "Button1Part", Type = typeof(Button))]
    [TemplatePart(Name = "Button2Part", Type = typeof(Button))]
    [TemplatePart(Name = "Button3Part", Type = typeof(Button))]
    [TemplateVisualState(Name = "None", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Hand", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Question", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Exclamation", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Asterisk", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Stop", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Error", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Warning", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "Information", GroupName = "MessageBoxTypeStates")]
    [TemplateVisualState(Name = "OK", GroupName = "MessageBoxButtonStates")]
    [TemplateVisualState(Name = "OKCancel", GroupName = "MessageBoxButtonStates")]
    [TemplateVisualState(Name = "AbortRetryIgnore", GroupName = "MessageBoxButtonStates")]
    [TemplateVisualState(Name = "YesNoCancel", GroupName = "MessageBoxButtonStates")]
    [TemplateVisualState(Name = "YesNo", GroupName = "MessageBoxButtonStates")]
    [TemplateVisualState(Name = "RetryCancel", GroupName = "MessageBoxButtonStates")]
    public class MessageBoxContent : ContentControl
    {
        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.DialogResultProperty"]/*'/>
        public static readonly DependencyProperty DialogResultProperty = DependencyProperty.Register("DialogResult", typeof(DialogResult), typeof(MessageBoxContent), new PropertyMetadata(DialogResult.None, MessageBoxContent.DialogResultPropertyChangedCallback));

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.MessageBoxButtonsProperty"]/*'/>
        public static readonly DependencyProperty MessageBoxButtonsProperty = DependencyProperty.Register("MessageBoxButtons", typeof(MessageBoxButtons), typeof(MessageBoxContent), new PropertyMetadata(MessageBoxButtons.OK, MessageBoxContent.MessageBoxButtonsPropertyChangedCallback));

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.MessageBoxDefaultButtonProperty"]/*'/>
        public static readonly DependencyProperty MessageBoxDefaultButtonProperty = DependencyProperty.Register("MessageBoxDefaultButton", typeof(MessageBoxDefaultButton), typeof(MessageBoxContent), new PropertyMetadata(MessageBoxDefaultButton.Button1, MessageBoxContent.MessageBoxDefaultButtonPropertyChangedCallback));

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.MessageBoxIconProperty"]/*'/>
        public static readonly DependencyProperty MessageBoxIconProperty = DependencyProperty.Register("MessageBoxIcon", typeof(MessageBoxIcon), typeof(MessageBoxContent), new PropertyMetadata(MessageBoxIcon.Asterisk, MessageBoxContent.MessageBoxIconPropertyChangedCallback));

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.MessageProperty"]/*'/>
        public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message", typeof(string), typeof(MessageBoxContent), new PropertyMetadata("Message", MessageBoxContent.MessagePropertyChangedCallback));

        private Button _button1Part;
        private Button _button2Part;
        private Button _button3Part;
        private FrameworkElement _layoutPart;
        private TextBlock _messagePart;

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.Constructor"]/*' />
        public MessageBoxContent()
        {
            this.DefaultStyleKey = typeof(MessageBoxContent);
        }

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.DialogResultChanged"]/*' />
        public event RoutedEventHandler DialogResultChanged;

        public event RoutedEventHandler ButtonClick;

        public DialogResult DialogResult
        {
            get
            {
                return (DialogResult)this.GetValue(DialogResultProperty);
            }

            set
            {
                this.SetValue(DialogResultProperty, value);
            }
        }

        public string Message
        {
            get
            {
                return (string)this.GetValue(MessageProperty);
            }

            set
            {
                this.SetValue(MessageProperty, value);
            }
        }

        public MessageBoxButtons MessageBoxButtons
        {
            get
            {
                return (MessageBoxButtons)this.GetValue(MessageBoxButtonsProperty);
            }

            set
            {
                this.SetValue(MessageBoxButtonsProperty, value);
            }
        }

        public MessageBoxDefaultButton MessageBoxDefaultButton
        {
            get
            {
                return (MessageBoxDefaultButton)this.GetValue(MessageBoxDefaultButtonProperty);
            }

            set
            {
                this.SetValue(MessageBoxDefaultButtonProperty, value);
            }
        }

        public MessageBoxIcon MessageBoxIcon
        {
            get
            {
                return (MessageBoxIcon)this.GetValue(MessageBoxIconProperty);
            }

            set
            {
                this.SetValue(MessageBoxIconProperty, value);
            }
        }

        private Button Button1Part
        {
            get
            {
                return this._button1Part;
            }

            set
            {
                Button oldButton1Part = this._button1Part;
                if (oldButton1Part != null)
                {
                    oldButton1Part.Click -= new RoutedEventHandler(this.Button1Part_Click);
                }

                this._button1Part = value;

                if (this._button1Part != null)
                {
                    this._button1Part.Click += new RoutedEventHandler(this.Button1Part_Click);
                }
            }
        }

        private Button Button2Part
        {
            get
            {
                return this._button2Part;
            }

            set
            {
                Button oldButton2Part = this._button2Part;
                if (oldButton2Part != null)
                {
                    oldButton2Part.Click -= new RoutedEventHandler(this.Button2Part_Click);
                }

                this._button2Part = value;

                if (this._button2Part != null)
                {
                    this._button2Part.Click += new RoutedEventHandler(this.Button2Part_Click);
                }
            }
        }

        private Button Button3Part
        {
            get
            {
                return this._button3Part;
            }

            set
            {
                Button oldButton3Part = this._button3Part;
                if (oldButton3Part != null)
                {
                    oldButton3Part.Click -= new RoutedEventHandler(this.Button3Part_Click);
                }

                this._button3Part = value;

                if (this._button3Part != null)
                {
                    this._button3Part.Click += new RoutedEventHandler(this.Button3Part_Click);
                }
            }
        }

        private FrameworkElement LayoutPart
        {
            get
            {
                return this._layoutPart;
            }

            set
            {
                FrameworkElement oldLayoutPart = this._layoutPart;
                if (oldLayoutPart != null)
                {
                    ////oldDialogPart.GotFocus -= new RoutedEventHandler(this.DialogPart_GotFocus);
                }

                this._layoutPart = value;

                if (this._layoutPart != null)
                {
                    ////this._dialogPart.GotFocus += new RoutedEventHandler(this.DialogPart_GotFocus);
                }
            }
        }

        private TextBlock MessagePart
        {
            get
            {
                return this._messagePart;
            }

            set
            {
                TextBlock oldMessagePart = this._messagePart;
                if (oldMessagePart != null)
                {
                }

                this._messagePart = value;

                if (this._messagePart != null)
                {
                }
            }
        }

        /// <include file='Documentation\MessageBoxContentDocumentation.uex' path='Members/Member[@for="MessageBoxContent.OnApplyTemplate"]/*' />
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.LayoutPart = (FrameworkElement)this.GetTemplateChild("LayoutPart");
            this.MessagePart = (TextBlock)this.GetTemplateChild("MessagePart");
            this.Button1Part = (Button)this.GetTemplateChild("Button1Part");
            this.Button2Part = (Button)this.GetTemplateChild("Button2Part");
            this.Button3Part = (Button)this.GetTemplateChild("Button3Part");

            this.ApplyMessageBoxButtonsState(false);
            this.ApplyMessageBoxIconState(false);
            this.OnMessageBoxDefaultButtonPropertyChanged(new DependencyPropertyChangedEventArgs());
        }

        protected virtual void OnButtonClick(RoutedEventArgs e)
        {
            if (this.ButtonClick != null)
            {
                this.ButtonClick(this, e);
            }
        }

        protected virtual void OnDialogResultChanged(RoutedEventArgs e)
        {
            if (this.DialogResultChanged != null)
            {
                this.DialogResultChanged(this, e);
            }
        }

        private static void DialogResultPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((MessageBoxContent)sender).OnDialogResultPropertyChanged(e);
        }

        private static void MessageBoxButtonsPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((MessageBoxContent)sender).OnMessageBoxButtonsPropertyChanged(e);
        }

        private static void MessageBoxDefaultButtonPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((MessageBoxContent)sender).OnMessageBoxDefaultButtonPropertyChanged(e);
        }

        private static void MessageBoxIconPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((MessageBoxContent)sender).OnMessageBoxIconPropertyChanged(e);
        }

        private static void MessagePropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((MessageBoxContent)sender).OnMessagePropertyChanged(e);
        }

        private void Button1Part_Click(object sender, RoutedEventArgs e)
        {
            this.DetermineDialogResult(1);

            this.OnButtonClick(new RoutedEventArgs());
        }

        private void Button2Part_Click(object sender, RoutedEventArgs e)
        {
            this.DetermineDialogResult(2);

            this.OnButtonClick(new RoutedEventArgs());
        }

        private void Button3Part_Click(object sender, RoutedEventArgs e)
        {
            this.DetermineDialogResult(3);

            this.OnButtonClick(new RoutedEventArgs());
        }

        private void DetermineDialogResult(int button)
        {
            if (button == 1)
            {
                switch (this.MessageBoxButtons)
                {
                    case MessageBoxButtons.OK:
                        this.DialogResult = DialogResult.OK;
                        break;

                    case MessageBoxButtons.OKCancel:
                        this.DialogResult = DialogResult.OK;
                        break;

                    case MessageBoxButtons.AbortRetryIgnore:
                        this.DialogResult = DialogResult.Abort;
                        break;

                    case MessageBoxButtons.YesNoCancel:
                        this.DialogResult = DialogResult.Yes;
                        break;

                    case MessageBoxButtons.YesNo:
                        this.DialogResult = DialogResult.Yes;
                        break;

                    case MessageBoxButtons.RetryCancel:
                        this.DialogResult = DialogResult.Retry;
                        break;
                }
            }
            else if (button == 2)
            {
                switch (this.MessageBoxButtons)
                {
                    case MessageBoxButtons.OKCancel:
                        this.DialogResult = DialogResult.Cancel;
                        break;

                    case MessageBoxButtons.AbortRetryIgnore:
                        this.DialogResult = DialogResult.Retry;
                        break;

                    case MessageBoxButtons.YesNoCancel:
                        this.DialogResult = DialogResult.No;
                        break;

                    case MessageBoxButtons.YesNo:
                        this.DialogResult = DialogResult.No;
                        break;

                    case MessageBoxButtons.RetryCancel:
                        this.DialogResult = DialogResult.Cancel;
                        break;
                }
            }
            else
            {
                switch (this.MessageBoxButtons)
                {
                    case MessageBoxButtons.AbortRetryIgnore:
                        this.DialogResult = DialogResult.Ignore;
                        break;

                    case MessageBoxButtons.YesNoCancel:
                        this.DialogResult = DialogResult.Cancel;
                        break;
                }
            }
        }

        private void ApplyMessageBoxButtonsState(bool useTransitions)
        {
            switch (this.MessageBoxButtons)
            {
                case MessageBoxButtons.OK:
                    VisualStateManager.GoToState(this, "OK", useTransitions);
                    break;

                case MessageBoxButtons.OKCancel:
                    VisualStateManager.GoToState(this, "OKCancel", useTransitions);
                    break;

                case MessageBoxButtons.AbortRetryIgnore:
                    VisualStateManager.GoToState(this, "AbortRetryIgnore", useTransitions);
                    break;

                case MessageBoxButtons.YesNoCancel:
                    VisualStateManager.GoToState(this, "YesNoCancel", useTransitions);
                    break;

                case MessageBoxButtons.YesNo:
                    VisualStateManager.GoToState(this, "YesNo", useTransitions);
                    break;

                case MessageBoxButtons.RetryCancel:
                    VisualStateManager.GoToState(this, "RetryCancel", useTransitions);
                    break;
            }
        }

        private void ApplyMessageBoxIconState(bool useTransitions)
        {
            switch (this.MessageBoxIcon)
            {
                case MessageBoxIcon.None:
                    VisualStateManager.GoToState(this, "None", useTransitions);
                    break;

                case MessageBoxIcon.Hand:
                    VisualStateManager.GoToState(this, "Hand", useTransitions);
                    break;

                case MessageBoxIcon.Question:
                    VisualStateManager.GoToState(this, "Question", useTransitions);
                    break;

                case MessageBoxIcon.Exclamation:
                    VisualStateManager.GoToState(this, "Exclamation", useTransitions);
                    break;

                case MessageBoxIcon.Asterisk:
                    VisualStateManager.GoToState(this, "Asterisk", useTransitions);
                    break;

                case MessageBoxIcon.Stop:
                    VisualStateManager.GoToState(this, "Stop", useTransitions);
                    break;

                case MessageBoxIcon.Error:
                    VisualStateManager.GoToState(this, "Error", useTransitions);
                    break;

                case MessageBoxIcon.Warning:
                    VisualStateManager.GoToState(this, "Warning", useTransitions);
                    break;

                case MessageBoxIcon.Information:
                    VisualStateManager.GoToState(this, "Information", useTransitions);
                    break;
            }
        }

        private void OnDialogResultPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            this.OnDialogResultChanged(new RoutedEventArgs());
        }

        private void OnMessageBoxButtonsPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            this.ApplyMessageBoxButtonsState(false);
        }

        private void OnMessageBoxDefaultButtonPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            switch (this.MessageBoxDefaultButton)
            {
                case MessageBoxDefaultButton.Button1:
                    if (this._button1Part != null)
                    {
                        this._button1Part.Focus();
                    }

                    break;

                case MessageBoxDefaultButton.Button2:
                    if (this._button2Part != null)
                    {
                        this._button2Part.Focus();
                    }

                    break;

                case MessageBoxDefaultButton.Button3:
                    if (this._button3Part != null)
                    {
                        this._button3Part.Focus();
                    }

                    break;
            }
        }

        private void OnMessageBoxIconPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            this.ApplyMessageBoxIconState(false);
        }

        private void OnMessagePropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (this._messagePart != null)
            {
                this._messagePart.Text = this.Message;
            }
        }
    }
}
